/*
 * This file is part of aion-lightning <aion-lightning.org>.
 * 
 * aion-lightning is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * aion-lightning is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with aion-lightning.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.aionengine.gameserver.services.vortexservice;

import com.aionengine.gameserver.model.gameobjects.Creature;
import com.aionengine.gameserver.model.gameobjects.Kisk;
import com.aionengine.gameserver.model.gameobjects.player.Player;
import com.aionengine.gameserver.model.gameobjects.player.RequestResponseHandler;
import com.aionengine.gameserver.model.team2.TeamType;
import com.aionengine.gameserver.model.team2.alliance.PlayerAlliance;
import com.aionengine.gameserver.model.team2.alliance.PlayerAllianceService;
import com.aionengine.gameserver.model.team2.group.PlayerGroupService;
import com.aionengine.gameserver.model.vortex.VortexLocation;
import com.aionengine.gameserver.model.vortex.VortexStateType;
import com.aionengine.gameserver.network.aion.serverpackets.SM_QUESTION_WINDOW;
import com.aionengine.gameserver.network.aion.serverpackets.SM_SYSTEM_MESSAGE;
import com.aionengine.gameserver.services.teleport.TeleportService2;
import com.aionengine.gameserver.utils.PacketSendUtility;
import javolution.util.FastMap;

/**
 * @author Source
 * @modif Dr2co
 */
public class Invasion extends DimensionalVortex<VortexLocation> {

    PlayerAlliance invAlliance, defAlliance;
    protected FastMap<Integer, Player> invaders = new FastMap<Integer, Player>();
    protected FastMap<Integer, Player> defenders = new FastMap<Integer, Player>();

    public Invasion(VortexLocation vortex) {
        super(vortex);
    }

    @Override
    public void startInvasion() {
        getVortexLocation().setActiveVortex(this);
        despawn();
        spawn(VortexStateType.INVASION);
        initRiftGenerator();
        updateAlliance();
    }

    @Override
    public void stopInvasion() {
        getVortexLocation().setActiveVortex(null);
        unregisterSiegeBossListeners();
        for (Kisk kisk : getVortexLocation().getInvadersKisks().values()) {
            kisk.getController().die();
        }
        for (Player invader : invaders.values()) {
            if (invader.isOnline()) {
                kickPlayer(invader, true);
            }
        }
        despawn();
        spawn(VortexStateType.PEACE);
    }

    @Override
    public void addPlayer(Player player, boolean isInvader) {
        FastMap<Integer, Player> list = isInvader ? invaders : defenders;
        PlayerAlliance alliance = isInvader ? invAlliance : defAlliance;

        if (alliance != null && alliance.size() > 0) {
            PlayerAllianceService.addPlayer(alliance, player);
        } else if (!list.isEmpty()) {
            Player first = null;

            for (Player firstOne : list.values()) {
                if (firstOne.isInGroup2()) {
                    PlayerGroupService.removePlayer(firstOne);
                } else if (firstOne.isInAlliance2()) {
                    PlayerAllianceService.removePlayer(firstOne);
                }
                first = firstOne;
            }

            if (first.getObjectId() != player.getObjectId()) {
                if (isInvader) {
                    invAlliance = PlayerAllianceService.createAlliance(first, player, TeamType.ALLIANCE_OFFENCE);
                } else {
                    defAlliance = PlayerAllianceService.createAlliance(first, player, TeamType.ALLIANCE_DEFENCE);
                }
            } else {
                kickPlayer(player, isInvader);
            }
        }
        list.putEntry(player.getObjectId(), player);
    }

    @Override
    public void kickPlayer(Player player, boolean isInvader) {
        FastMap<Integer, Player> list = isInvader ? invaders : defenders;
        PlayerAlliance alliance = isInvader ? invAlliance : defAlliance;

        list.remove(player.getObjectId());

        if (alliance != null && alliance.hasMember(player.getObjectId())) {
            if (player.isOnline()) {
                PacketSendUtility.sendPacket(player, new SM_SYSTEM_MESSAGE(isInvader ? 1401452 : 1401476));
            }
            PlayerAllianceService.removePlayer(player);
            if (alliance.size() == 0) {
                if (isInvader) {
                    invAlliance = null;
                } else {
                    defAlliance = null;
                }
            }
        }

        if (isInvader && player.isOnline()
                && player.getWorldId() == getVortexLocation().getInvasionWorldId()) {
            // You will be returned to where you entered.
            PacketSendUtility.sendPacket(player, new SM_SYSTEM_MESSAGE(1401474));
            TeleportService2.teleportTo(player, getVortexLocation().getHomePoint());
        }

        getVortexLocation().getVortexController().getPassedPlayers().remove(player.getObjectId());
        getVortexLocation().getVortexController().syncPassed(true);
    }

    @Override
    public void updateDefenders(Player defender) {
        if (defenders.containsKey(defender.getObjectId())) {
            return;
        }

        if (defAlliance == null || !defAlliance.isFull()) {
            RequestResponseHandler responseHandler = new RequestResponseHandler(defender) {
                @Override
                public void acceptRequest(Creature requester, Player responder) {
                    if (responder.isInGroup2()) {
                        PlayerGroupService.removePlayer(responder);
                    } else if (responder.isInAlliance2()) {
                        PlayerAllianceService.removePlayer(responder);
                    }

                    if (defAlliance == null || !defAlliance.isFull()) {
                        addPlayer(responder, false);
                    }
                }

                @Override
                public void denyRequest(Creature requester, Player responder) {
                    // do nothing
                }

            };

            boolean requested = defender.getResponseRequester().putRequest(904306, responseHandler);
            if (requested) {
                PacketSendUtility.sendPacket(defender, new SM_QUESTION_WINDOW(904306, 0, 0));
            }
        }
    }

    @Override
    public void updateInvaders(Player invader) {
        if (invaders.containsKey(invader.getObjectId())) {
            return;
        }

        addPlayer(invader, true);
    }

    private void updateAlliance() {
        for (Player player : getVortexLocation().getPlayers().values()) {
            if (player.getRace().equals(getVortexLocation().getDefendersRace())) {
                updateDefenders(player);
            }
        }
    }

    @Override
    public FastMap<Integer, Player> getInvaders() {
        return invaders;
    }

    @Override
    public FastMap<Integer, Player> getDefenders() {
        return defenders;
    }

}